<<<<<<< HEAD
Bryan GunerAug 24·22 min read
PEP8 : Python Enhancement Proposals, style-guide for Python.
print
is the equivalent of console.log.
#
is used to make comments in your
code.
def foo():"""The foo function does many amazing things that youshould not question. Just accept that it exists anduse it with caution."""secretThing()
Python has a built in help function that let’s you see a description of the source code without having to navigate to it.
Python has three types of numbers:
Integer
Positive and Negative Counting Numbers.
No Decimal Point
Created by a literal non-decimal pt
number or with the int()
constructor.
print(3) # => 3 print(int(19)) # => 19 print(int()) # => 0
Boolean is a subtype of integer in Python.
Floating Point Number
Decimal Numbers.
print(2.24) # => 2.24 print(2.) # => 2.0 print(float()) # => 0.0 print(27e-5) # => 0.00027
Consist of a real part and imaginary part.
The i
is switched to a j
in programming.
print(7j) # => 7j print(5.1+7.7j)) # => 5.1+7.7j print(complex(3, 5)) # => 3+5j print(complex(17)) # => 17+0j print(complex()) # => 0j
# Using Floatprint(17) # => 17print(float(17)) # => 17.0# Using Intprint(17.0) # => 17.0print(int(17.0)) # => 17# Using Strprint(str(17.0) + ' and ' + str(17)) # => 17.0 and 17
The arithmetic operators are the same between JS and Python, with two additions:
“**” : Double asterisk for exponent.
“//” : Integer Division.
There are no spaces between math operations in Python.
Integer Division gives the other part
of the number from Module; it is a way
to do round down numbers replacing Math.floor()
in JS.
There are no ++
and --
in Python, the only shorthand
operators are:
Python uses both single and double quotes.
You can escape strings like so 'Jodi asked,
"What\'s up,
Sam?"'
Multiline strings use triple quotes.
print('''My instructions are very long so to make themmore readable in the code I am putting them onmore than one line. I can even include "quotes"of any kind because they won't get confused withthe end of the string!''')
Use the len()
function to get the length of a
string.
print(len("Spaghetti")) # => 9
Python uses zero-based indexing
Python allows negative indexing (thank god!)
print("Spaghetti"[-1]) # => i print("Spaghetti"[-4]) # => e
Python let’s you use ranges
print("Spaghetti"[1:4]) # => pag print("Spaghetti"[4:-1]) # => hett print("Spaghetti"[4:4]) # => (empty string)
The end range is exclusive just like slice
in JS.
# Shortcut to get from the beginning of a string to a certain index.print("Spaghetti"[:4]) # => Spagprint("Spaghetti"[:-1]) # => Spaghett# Shortcut to get from a certain index to the end of a string.print("Spaghetti"[1:]) # => paghettiprint("Spaghetti"[-4:]) # => etti
The index
string function is the equiv. of indexOf()
in JS
print("Spaghetti".index("h")) # => 4print("Spaghetti".index("t")) # => 6
The count
function finds out how many times a
substring appears in a string.
print("Spaghetti".count("h")) # => 1print("Spaghetti".count("t")) # => 2print("Spaghetti".count("s")) # => 0print('''We choose to go to the moon in this decade and do the other things,not because they are easy, but because they are hard, because that goal willserve to organize and measure the best of our energies and skills, because thatchallenge is one that we are willing to accept, one we are unwilling topostpone, and one which we intend to win, and the others, too.'''.count('the ')) # => 4
You can use +
to concatenate strings, just like in
JS.
You can also use “*” to repeat strings or multiply strings.
Use the format()
function to use placeholders in a
string to input values later on.
first_name = "Billy"last_name = "Bob"print('Your name is {0} {1}'.format(first_name, last_name)) # => Your name is Billy Bob
Shorthand way to use format function
is: print(f'Your name is
{first_name}
{last_name}')
Some useful string methods.
Note that in JS join
is used on an Array, in Python it is
used on String.
There are also many handy testing methods.
Duck-Typing : Programming Style which avoids checking an object’s type to figure out what it can do.
Duck Typing is the fundamental approach of Python.
Assignment of a value automatically declares.
a = 7b = 'Marbles'print(a) # => 7print(b) # => Marbles
You can chain variable assignments to give multiple var names the same value.
Use with caution as this is highly unreadable
count = max = min = 0print(count) # => 0print(max) # => 0print(min) # => 0
The value and type of a variable can be re-assigned at any time.
a = 17print(a) # => 17a = 'seventeen'print(a) # => seventeen
NaN
does not exist in Python, but you can
'create' it like so: print(float("nan"))
Python replaces null
with none.
none
is an object and can be directly
assigned to a variable.
Using none is a convenient way to check to see why an action may not be operating correctly in your program.
One of the biggest benefits of Python is that it reads more like English than JS does.
# Logical ANDprint(True and True) # => Trueprint(True and False) # => Falseprint(False and False) # => False# Logical ORprint(True or True) # => Trueprint(True or False) # => Trueprint(False or False) # => False# Logical NOTprint(not True) # => Falseprint(not False and True) # => Trueprint(not True or False) # => False
By default, Python considers an object to be true UNLESS it is one of the following:
Constant None
or False
Zero of any numeric type.
Empty Sequence or Collection.
True
and False
must be capitalized
Python uses all the same equality operators as JS.
In Python, equality operators are processed from left to right.
Logical operators are processed in this order:
NOT
AND
OR
Just like in JS, you can use parentheses
to change the inherent order of
operations.
Short Circuit
: Stopping a program when a true
or false
has been reached.
print (2 == '2') # => Falseprint (2 is '2') # => Falseprint ("2" == '2') # => Trueprint ("2" is '2') # => True# There is a distinction between the number types.print (2 == 2.0) # => Trueprint (2 is 2.0) # => False
In the Python community it is better
to use is
and is not
over ==
or !=
if name == 'Monica':print('Hi, Monica.')if name == 'Monica':print('Hi, Monica.')else:print('Hello, stranger.')if name == 'Monica':print('Hi, Monica.')elif age < 12:print('You are not Monica, kiddo.')elif age > 2000:print('Unlike you, Monica is not an undead, immortal vampire.')elif age > 100:print('You are not Monica, grannie.')
Remember the order of elif
statements matter.
spam = 0while spam < 5:print('Hello, world.')spam = spam + 1
Break
statement also exists in Python.
spam = 0while True:print('Hello, world.')spam = spam + 1if spam >= 5:break
As are continue
statements
spam = 0while True:print('Hello, world.')spam = spam + 1if spam < 5:continuebreak
Python equivalent to try/catch
a = 321try:print(len(a))except:print('Silently handle error here') # Optionally include a correction to the issuea = str(a)print(len(a)a = '321'try:print(len(a))except:print('Silently handle error here') # Optionally include a correction to the issuea = str(a)print(len(a))
You can name an error to give the output more specificity.
a = 100b = 0try:c = a / bexcept ZeroDivisionError:c = Noneprint(c)
You can also use the pass
commmand to by pass a certain
error.
a = 100b = 0try:print(a / b)except ZeroDivisionError:pass
The pass
method won't allow you to bypass
every single error so you can chain an
exception series like so:
a = 100# b = "5"try:print(a / b)except ZeroDivisionError:passexcept (TypeError, NameError):print("ERROR!")
You can use an else
statement to end a chain of except
statements.
# tuple of file namesfiles = ('one.txt', 'two.txt', 'three.txt')# simple loopfor filename in files:try:# open the file in read modef = open(filename, 'r')except OSError:# handle the case where file does not exist or permission is deniedprint('cannot open file', filename)else:# do stuff with the file object (f)print(filename, 'opened successfully')print('found', len(f.readlines()), 'lines')f.close()
finally
is used at the end to clean up all
actions under any circumstance.
def divide(x, y):try:result = x / yexcept ZeroDivisionError:print("Cannot divide by zero")else:print("Result is", result)finally:print("Finally...")
Using duck typing to check to see if some value is able to use a certain method.
# Try a number - nothing will print outa = 321if hasattr(a, '__len__'):print(len(a))# Try a string - the length will print out (4 in this case)b = "5555"if hasattr(b, '__len__'):print(len(b))
Pass Keyword is required to write the JS equivalent of :
if (true) {}while (true) {}if True:passwhile True:pass
Function definition includes:
The def
keyword
The name of the function
A list of parameters enclosed in parentheses.
A colon at the end of the line.
One tab indentation for the code to run.
def printCopyright():print("Copyright 2020. Me, myself and I. All rights reserved.")
You can use default parameters just like in JS
def greeting(name, saying="Hello"):print(saying, name)greeting("Monica")# Hello Monicagreeting("Barry", "Hey")# Hey Barry
Keep in mind, default parameters must always come after regular parameters.
# THIS IS BAD CODE AND WILL NOT RUNdef increment(delta=1, value):return delta + value
You can specify arguments by name without destructuring in Python.
def greeting(name, saying="Hello"):print(saying, name)# name has no default value, so just provide the value# saying has a default value, so use a keyword argumentgreeting("Monica", saying="Hi")
The lambda
keyword is used to create anonymous
functions and are supposed to be one-liners.
toUpper = lambda s: s.upper()
Remember that in Python join()
is called on a string with an
array/list passed in as the
argument.
shopping_list = ['bread','milk','eggs']print(','.join(shopping_list))
Python has a very powerful formatting engine.
format()
is also applied directly to
strings.
# Comma Thousands Separatorprint('{:,}'.format(1234567890))'1,234,567,890'# Date and Timed = datetime.datetime(2020, 7, 4, 12, 15, 58)print('{:%Y-%m-%d %H:%M:%S}'.format(d))'2020-07-04 12:15:58'# Percentagepoints = 190total = 220print('Correct answers: {:.2%}'.format(points/total))Correct answers: 86.36%# Data Tableswidth=8print(' decimal hex binary')print('-'*27)for num in range(1,16):for base in 'dXb':print('{0:{width}{base}}'.format(num, base=base, width=width), end=' ')print()
Python runs synchronously, all programs and processes will stop when listening for a user input.
The input
function shows a prompt to a user and
waits for them to type
'ENTER'.
Programming Script : A set of code that runs in a linear fashion.
The largest difference between scripts and programs is the level of complexity and purpose. Programs typically have many UI’s.
Python can be used to display html, css, and JS.
We will be using Python as an API (Application Programming Interface)
Sequence : The most basic data structure in Python where the index determines the order.
List
Tuple
Range
Collections : Unordered data structures, hashable values.
Dictionaries
Sets
Iterable : Generic name for a sequence or collection; any object that can be iterated through.
Can be mutable or immutable.
Lists are the python equivalent of arrays.
empty_list = []departments = ['HR','Development','Sales','Finance','IT','Customer Support']# You can instantiatespecials = list()# Test if a value is in a list.print(1 in [1, 2, 3]) #> Trueprint(4 in [1, 2, 3]) #> False
Tuples
: Very similar to lists, but they are immutable
# Instantiated with parenthesestime_blocks = ('AM','PM')# Sometimes instantiated withoutcolors = 'red','blue','green'numbers = 1, 2, 3# Tuple() built in can be used to convert other data into a tupletuple('abc') # returns ('a', 'b', 'c')tuple([1,2,3]) # returns (1, 2, 3)
Think of tuples as constant variables.
Ranges
: A list of numbers which can’t be
changed; often used with for
loops.
Declared using one to three parameters.
Start : opt. default 0, first # in sequence.
Stop
: required
next number past the last number in
the sequence.
Step : opt. default 1, difference between each number in the sequence.
range(5) # [0, 1, 2, 3, 4]range(1,5) # [1, 2, 3, 4]range(0, 25, 5) # [0, 5, 10, 15, 20]range(0) # [ ]for let (i = 0; i < 5; i++)for let (i = 1; i < 5; i++)for let (i = 0; i < 25; i+=5)for let(i = 0; i = 0; i++)
Keep in mind that stop
is not included in the range.
Dictionaries
: Mappable collection where a hashable
value is used as a key to ref. an
object stored in the dictionary.
Mutable.
a = {'one':1, 'two':2, 'three':3}b = dict(one=1, two=2, three=3)c = dict([('two', 2), ('one', 1), ('three', 3)])
a, b, and c are all equal
Declared with curly braces of the
built in dict()
Benefit of dictionaries in Python is that it doesn’t matter how it is defined, if the keys and values are the same the dictionaries are considered equal.
Use the in
operator to see if a key exists in a
dictionary.
Always be unique, duplicate items are auto dropped from the set.
Common Uses:
Removing Duplicates
Membership Testing
Mathematical Operators: Intersection, Union, Difference, Symmetric Difference.
Standard Set is mutable, Python has a
immutable version called frozenset.
Sets created by putting comma seperated values inside braces:
school_bag = {'book','paper','pencil','pencil','book','book','book','eraser'}print(school_bag)# Also can use set constructor to automatically put it into a set.letters = set('abracadabra')print(letters)
Functions using iterables
filter(function, iterable) : creates new iterable of the same type which includes each item for which the function returns true.
map(function, iterable) : creates new iterable of the same type which includes the result of calling the function on every item of the iterable.
sorted(iterable, key=None, reverse=False) : creates a new sorted list from the items in the iterable.
Output is always a list
key: opt function which coverts and item
to a value to be compared.
reverse: optional boolean.
enumerate(iterable, start=0) : starts with a sequence and converts it to a series of tuples
quarters = ['First', 'Second', 'Third', 'Fourth']print(enumerate(quarters))print(enumerate(quarters, start=1))# (0, 'First'), (1, 'Second'), (2, 'Third'), (3, 'Fourth')# (1, 'First'), (2, 'Second'), (3, 'Third'), (4, 'Fourth')
zip(*iterables) : creates a zip object filled with tuples that combine 1 to 1 the items in each provided iterable.
Functions that analyze iterables
len(iterable) : returns the count of the number of items.
max(*args, key=None) : returns the largest of two or more arguments.
max(iterable, key=None) : returns the largest item in the iterable.
key
optional function which converts an
item to a value to be compared.
min
works the same way as max
sum(iterable) : used with a list of numbers to generate the total.
There is a faster way to concatenate an array of strings into one string, so do not use sum for that.
any(iterable) : returns True if any items in the iterable are true.
all(iterable) : returns True is all items in the iterable are true.
Working with dictionaries
dir(dictionary) : returns the list of keys in the dictionary.
Working with sets
Union
: The pipe | operator or union(*sets)
function can be used to produce a new
set which is a combination of all
elements in the provided set.
a = {1, 2, 3}b = {2, 4, 6}print(a | b) # => {1, 2, 3, 4, 6}
Intersection : The & operator ca be used to produce a new set of only the elements that appear in all sets.
a = {1, 2, 3}b = {2, 4, 6}print(a & b) # => {2}
Difference : The — operator can be used to produce a new set of only the elements that appear in the first set and NOT the others.
Symmetric Difference : The ^ operator can be used to produce a new set of only the elements that appear in exactly one set and not in both.
a = {1, 2, 3}b = {2, 4, 6}print(a - b) # => {1, 3}print(b - a) # => {4, 6}print(a ^ b) # => {1, 3, 4, 6}
In python, there is only one for loop.
Always Includes:
The for
keyword
A variable name
The in
keyword
An iterable of some kid
A colon
On the next line, an indented block
of code called the for
clause.
You can use break
and continue
statements inside for loops as
well.
You can use the range function as the
iterable for the for
loop.
print('My name is')for i in range(5):print('Carlita Cinco (' + str(i) + ')')total = 0for num in range(101):total += numprint(total)
Looping over a list in Python
for c in ['a', 'b', 'c']:print(c)lst = [0, 1, 2, 3]for i in lst:print(i)
Common technique is to use the len() on a pre-defined list with a for loop to iterate over the indices of the list.
supplies = ['pens', 'staplers', 'flame-throwers', 'binders']for i in range(len(supplies)):print('Index ' + str(i) + ' in supplies is: ' + supplies[i])
You can loop and destructure at the same time.
l = [[1, 2], [3, 4], [5, 6]]for a, b in l:print(a, ', ', b)# Prints 1, 2# Prints 3, 4# Prints 5, 6
You can use values()
and keys()
to loop over dictionaries.
spam = {'color': 'red', 'age': 42}for v in spam.values():print(v)# Prints red# Prints 42for k in spam.keys():print(k)# Prints color# Prints age
For loops can also iterate over both keys and values.
# Getting tuplesfor i in spam.items():print(i)# Prints ('color', 'red')# Prints ('age', 42)# Destructuring to valuesfor k, v in spam.items():print('Key: ' + k + ' Value: ' + str(v))# Prints Key: age Value: 42# Prints Key: color Value: red
Looping over string
for c in "abcdefg":print(c)
Variable-length positional arguments : (*args)
def add(a, b, *args):total = a + b;for n in args:total += nreturn totaladd(1, 2) # Returns 3add(2, 3, 4, 5) # Returns 14
keyword arguments : (*kwargs)
def print_names_and_countries(greeting, **kwargs):for k, v in kwargs.items():print(greeting, k, "from", v)print_names_and_countries("Hi",Monica="Sweden",Charles="British Virgin Islands",Carlo="Portugal")# Prints# Hi Monica from Sweden# Hi Charles from British Virgin Islands# Hi Carlo from Portugal
When you order arguments within a function or function call, the args need to occur in a particular order:
formal positional args.
*args
keyword args with default values
**kwargs
def example(arg_1, arg_2, *args, **kwargs):passdef example2(arg_1, arg_2, *args, kw_1="shark", kw_2="blowfish", **kwargs):pass
Modules are similar to packages in Node.js
Come in different types: Built-In, Third-Party, Custom.
All loaded using import
statements.
Terms
module : Python code in a separate file.
package : Path to a directory that contains modules.
**init.py** : Default file for a package.
submodule : Another file in a module’s folder.
function : Function in a module.
A module can be any file but it is
usually created by placing a special
file __init__.py
into a folder.
Try to avoid importing with wildcards in Python.
Use multiple lines for clarity when importing.
from urllib.request import (HTTPDefaultErrorHandler as ErrorHandler,HTTPRedirectHandler as RedirectHandler,Request,pathname2url,url2pathname,urlopen,)
Python 3 removed <>
and only uses !=
format()
was introduced with P3
All strings in P3 are unicode and encoded.
md5
was removed.
ConfigParser
was renamed to configparser
sets
were killed in favor of set()
class.
print
was a statement in P2, but is a
function in P3.
Classes are a way of combining information and behavior.
Classes are blueprints to make objects.
class AngryBird {constructor() {this.x = 0;this.y = 0;}}class AngryBird:def __init__(self):"""Construct a new AngryBird by setting its position to (0, 0)."""self.x = 0self.y = 0
Both JS and PY use the class
keyword to declare classes.
constructor
== __init__
this
== self
bird = AngryBird()print(bird.x, bird.y) #> 0 0class AngryBird:def __init__(self):"""Construct a new AngryBird by setting its position to (0, 0)."""self.x = 0self.y = 0 def move_up_by(self, delta):self.y += delta
Note how you do not need to define self
it is already bound to the
class.
It is good practice to write a comment at the beginning of your class, describing the class.
Dunder Methods
Double Underscore Methods, special built in functions that PY uses in certain ways.
i.e. __init__()
lets you make sure all relevant
attributes are set to their proper
values when an object is created from
the class.
The self
keyword refers to the current object
that you are working with.
Method is a function that is part of a class.
class AngryBird:def __init__(self):self.x = 0self.y = 0 def move_up_by(self, delta):self.y += deltabird = AngryBird()print(bird)print(bird.y)bird.move_up_by(5)print(bird.y)
Use one leading underscore only for non-public methods and instance variables
class AngryBird:def __init__(self, x=0, y=0):"""Construct a new AngryBird by setting its position to (0, 0)."""self._x = xself._y = y def move_up_by(self, delta):self._y += delta def get_x(self):return self._x def get_y(self):return self._y
All instance variables should be considered non-public
**slots** : Dunder class variable used to reserve memory for the instance variables that you know will you will use.
class AngryBird:__slots__ = ['_x', '_y'] def __init__(self, x=0, y=0):"""Construct a new AngryBird by setting its position to (0, 0)."""self._x = xself._y = y def move_up_by(self, delta):self._y += delta def get_x(self):return self._x def get_y(self):return self._y
You can use __repr__()
to override the behavior of printing
out a class in a verbose manner.
class AngryBird:__slots__ = ['_x', '_y'] def __init__(self, x=0, y=0):"""Construct a new AngryBird by setting its position to (0, 0)."""self._x = xself._y = y def move_up_by(self, delta):self._y += delta def get_x(self):return self._x def get_y(self):return self._y def __repr__(self):return f"<AngryBird ({self._x}, {self._y})>"
Getters and Setters are used in object-oriented programming to add validation logic around getting and setting a value.
Getters
bird = AngryBird()print(bird.get_x(), bird.get_y())
Getting the x and y values of our class can get very cumbersome.
Decorators : Allow us to change the way methods get invoked.
Always start with the @ symbol.
Can be applied to methods, classes, and parameters.
Built in decorator named property
that you can apply to a method to make
it readable.
@propertydef x(self):return self._x @propertydef y(self):return self._y bird = AngryBird() print(bird.x, bird.y)
Setters
class AngryBird:def __init__(self, x=0, y=0):"""Construct a new AngryBird by setting its position to (0, 0)."""self._x = xself._y = y def move_up_by(self, delta):self._y += delta @propertydef x(self):return self._x @x.setterdef x(self, value):if value < 0:value = 0self._x = value @propertydef y(self):return self._y @y.setterdef y(self, value):if value < 0:value = 0self._y = value
List comprehensions are the equivalent of wrapped up filter namp array methods while also allowing nested loops.
new_list = [expression for member
in iterable]
expression : member itself, a call to a methd, or any other valid expression that returns a value.
member : object or value in the list or iterable.
iterable : iterable.
new_list = [expression for member in
iterable (if conditional)]
Adding a conditional into a list comprehension.
sentence = 'Mary, Mary, quite contrary, how does your garden grow?'def is_consonant(letter):vowels = "aeiou"return letter.isalpha() and letter.lower() not in vowelsconsonants = [i for i in sentence if is_consonant(i)]print(consonants)# Prints ['M', 'r', 'y', 'M', 'r', 'y', 'q', 't', 'c',# 'n', 't', 'r', 'r', 'y', 'h', 'w', 'd', 's', 'y',# 'r', 'g', 'r', 'd', 'n', 'g', 'r', 'w']
When to not use list comprehensions
List comprehensions may make your code run more slowly or use more memory.
You can use nest lists to create matrices.
matrix = [[i for i in range(5)] for _ in range(6)]print(matrix)# Prints# [# [0, 1, 2, 3, 4],# [0, 1, 2, 3, 4],# [0, 1, 2, 3, 4],# [0, 1, 2, 3, 4],# [0, 1, 2, 3, 4],# [0, 1, 2, 3, 4]# ]
Algorithms — Solved algorithms and data structures problems in many languages.
Algorithm Visualizer — Interactive online platform that visualizes algorithms from code.
Quadsort — Stable non-recursive merge sort named quadsort.
System design algorithms — Algorithms you should know before system design.
Wolfsort — Stable adaptive hybrid radix / merge sort.
Evolutionary Computation Bestiary — Bestiary of evolutionary, swarm and other metaphor-based algorithms.
Elements of Programming book — Decomposing programs into a system of algorithmic components. (Review) (HN) (Lobsters)
CPP/C — C/C++ algorithms/DS problems.
Elementary Algorithms — Introduces elementary algorithms and data structures. Includes side-by-side comparisons of purely functional realization and their imperative counterpart.
The Sound of Sorting — Visualization and “Audibilization” of Sorting Algorithms. (Web)
Open Data Structures — Provide a high-quality open content data structures textbook that is both mathematically rigorous and provides complete implementations. (Code)
Anna — Low-latency, cloud-native KVS.
The Daily Coding newsletter — Master JavaScript and Data Structures.
Michael Scott — Nonblocking data structures lectures (2020) — Nonblocking concurrent data structures are an increasingly valuable tool for shared-memory parallel programming.
Morphisms of Computational Constructs — Visual catalogue + story of morphisms displayed across computational structures.
cdb — Fast, reliable, simple package for creating and reading constant databases.
=======
e4bf9b77d4b065ed20f39ffb8a1f8425c6ab66cf
First things first, the repo with all the exercises of this lecture is right here:
Let's begin!
1) Find prime factors.
For the very basics, let's start with something unusual: Public Key Encryption. This technique relies on certain really large numbers being computationally hard to factor to keep data secure. In this first exercise I'll factor some numbers that are easy to deal with; the goal is to create a Python function to find all prime factors, I'll do it by taking an integer value as input and the return or output will be a list of prime factors.
In this solution I decided to search for factors by dividing the given sequentially larger values (starting from 2) to see which one divide evenly into it, without leaving a remainder behind:
As you can see I'm calling the function with the 500 number, so it will begin with 2 as the original divisor, then it'll go on keep dividing until the remainder is no longer an even number, in this case resulting in the result of 2, 2, 5, and finally 5:
2) Identifying Palindromes.
This a very usual programming and software engineering exercise, maybe you already did it on colleague, school or watching another tutorial, it's a very cool puzzle to solve because involves pattern recognition, logic and of course coding.
In case it's your first time dealing with palindromes, a palindrome is a word or text that reads exactly the same, either forwards or backwards.
Again, I'll write a function to detect palindromes, where my input will be the string I'm checking and the result or output is going to be a boolean value (false/true):
Going line by line, first I'm importing the "re" library, which contains regular expressions to extract letters from an input string, then I'm defining a "palindrome" function that receives a "string" parameter. Then I use the lower operator in the input string to convert all of the letters to lowercase, then I pass the result to the regular expression "findall" function with a pattern that will search for combinations of one or more letters. Tat will produce a list with all of the matched sub-strings that I merged together into a single string using the "join" function.
Then I slice the entire string, with the stride set to negative one, meaning I'll get a copy of the original string in reverse order.
Finally, I'm comparing both strings and return it:
3) Sort a string.
Another common task in programming is sorting things.
The goal is to create a Python function that sorts the words within a given string.
The input will be a list of words separated by spaces, and the result or output will be the same string of words sorted alphabetically:
My "sorted" function starts with the "split" method, which breaks apart the input string at each of the spaces and gives me a list of the individual word.
Then, to ignore the capitalization (if there is any) in the loop I convert each word within the list into lower case, to later on sort the entire list:
4) The waiting game.
For this exercise I'll write a Python function, which is when invoked it'll print a message to wait a random amount of time.
The user press enters, then the timer starts. The user's goal is to wait the specified number of seconds in the message, and then press enter again.
For this exercise I used to modules, "time" module to measure the amount of time, and the "random" module to generate a random number of seconds.
The input function prompts the user to press enter to begin and then blocks the execution until the user hits enter again.
5) Generate a new password.
For this final example, I'll implement a function based on the "Diceware" method, which is a method for creating passphrases and passwords using the numbers of an ordinary dice as hardware random number generator. It involves a list of over 7000 different words.
Instead of rolling a physical dice, I'll write a Python function that simulates this behavior.
The input will be a number of words in a passphrase and the output or result will be a string of random words, separated by spaces.
For this one, I could've used the "random" module, but instead I went for the "secret" module, since the random module is not recommended when dealing with cryptographic procedures:
My function begins by getting the number of words, then opening the "diceware.wordlist.asc" file with a context manager and then uses "readlines" function to get a list with each of the lines within the file.
The top of the file diceware that I used has two extra lines before the word list actually begins, and at the bottom there are also several extra lines for a PGP signature:
So I indexed out the 7K (7776) lines from the middle of the file that I actually care about. Remembering that each of these lines contain both a five-digit number and the corresponding word, I used the split method to break them apart, and then build the list containing just the words.
Then I used the "secrets.choice" function within another list comprehension to build a list with the desired number of random words.
And finally, I used the join method to combine the random words into a single string with spaces between them:
bandersnatch
is a PyPI mirroring client designed to
efficiently create a complete mirror of the
contents of PyPI. Organizations thus save
bandwidth and latency on package downloads
(especially in the context of automated
tests) and to prevent heavily loading PyPI’s
Content Delivery Network (CDN).
Docs | Issues | GitHub | PyPI
build
is a
PEP 517
compatible Python package builder. It
provides a CLI to build packages, as well as
a Python API.
Docs | Issues | GitHub | PyPI | Discussions | Discord #cibuildwheel
cibuildwheel
is a Python package that builds
wheels
for all common platforms and Python versions
on most CI systems. Also see
multibuild.
Docs | Issues | Bitbucket | PyPI
distlib
is a library which implements low-level
functions that relate to packaging and
distribution of Python software. distlib
implements several relevant PEPs (Python
Enhancement Proposal standards) and is
useful for developers of third-party
packaging tools to make and upload binary
and source
distributions, achieve interoperability, resolve
dependencies, manage package resources, and
do other similar functions.
Unlike the stricter
packaging
project (below), which specifically
implements modern Python packaging
interoperability standards, distlib
also attempts to provide reasonable fallback
behaviours when asked to handle legacy
packages and metadata that predate the
modern interoperability standards and fall
into the subset of packages that are
incompatible with those standards.
Docs | Issues | GitHub | PyPI
Core utilities for Python packaging used by pip and setuptools.
The core utilities in the packaging library handle version handling, specifiers, markers, requirements, tags, and similar attributes and tasks for Python packages. Most Python users rely on this library without needing to explicitly call it; developers of the other Python packaging, distribution, and installation tools listed here often use its functionality to parse, discover, and otherwise handle dependency attributes.
This project specifically focuses on implementing the modern Python packaging interoperability standards defined at PyPA specifications, and will report errors for sufficiently old legacy packages that are incompatible with those standards. In contrast, the distlib project is a more permissive library that attempts to provide a plausible reading of ambiguous metadata in cases where packaging will instead report on error.
Docs | Issues | GitHub | PyPI
The most popular tool for installing Python packages, and the one included with modern versions of Python.
It provides the essential core features for finding, downloading, and installing packages from PyPI and other Python package indexes, and can be incorporated into a wide range of development workflows via its command-line interface (CLI).
Docs | Source | Issues | PyPI
Pipenv is a project that aims to bring the best of all packaging worlds to the Python world. It harnesses Pipfile, pip, and virtualenv into one single toolchain. It features very pretty terminal colors.
Pipenv aims to help users manage environments, dependencies, and imported packages on the command line. It also works well on Windows (which other tools often underserve), makes and checkes file hashes, to ensure compliance with hash-locked dependency specifiers, and eases uninstallation of packages and dependencies. It is used by Python users and system administrators, but has been less maintained since late 2018.
Source
Pipfile
and its sister Pipfile.lock
are a higher-level application-centric
alternative to
pip’s lower-level requirements.txt
file.
pipx is a tool to install and run Python command-line applications without causing dependency conflicts with other packages installed on the system.
This guide!
GitHub and docs | PyPI
readme_renderer
is a library that package developers use to
render their user documentation (README)
files into HTML from markup languages such
as Markdown or reStructuredText. Developers
call it on its own or via
twine, as part of their release management
process, to check that their package
descriptions will properly display on
PyPI.
Docs | Issues | GitHub | PyPI
setuptools (which includes easy_install) is a collection of enhancements to the
Python distutils that allow you to more
easily build and distribute Python
distributions, especially ones that have dependencies on
other packages.
distribute was a fork of setuptools that was merged back into setuptools (in v0.7), thereby making setuptools the primary choice for Python packaging.
trove-classifiers is the canonical source for classifiers on PyPI, which project maintainers use to systematically describe their projects so that users can better find projects that match their needs on the PyPI.
The trove-classifiers package contains a list of valid classifiers and deprecated classifiers (which are paired with the classifiers that replace them). Use this package to validate classifiers used in packages intended for uploading to PyPI. As this list of classifiers is published as code, you can install and import it, giving you a more convenient workflow compared to referring to the list published on PyPI. The issue tracker for the project hosts discussions on proposed classifiers and requests for new classifiers.
Docs | Issues | GitHub | PyPI
Twine is the primary tool developers use to upload packages to the Python Package Index or other Python package indexes. It is a command-line program that passes program files and metadata to a web API. Developers use it because it’s the official PyPI upload tool, it’s fast and secure, it’s maintained, and it reliably works.
Docs | Issues | GitHub | PyPI
virtualenv is a tool which uses the command-line path environment variable to create isolated Python Virtual Environments, much as venv does. virtualenv provides additional functionality, compared to venv, by supporting Python 2.7 and by providing convenient features for configuring, maintaining, duplicating, and troubleshooting the virtual environments. For more information, see the section on Creating Virtual Environments.
The current codebase powering the Python Package Index (PyPI). It is hosted at pypi.org. The default source for pip downloads.
Docs | Issues | GitHub | PyPI
Primarily, the wheel project offers the bdist_wheel
setuptools
extension for creating
wheel distributions. Additionally, it offers its own command
line utility for creating and installing
wheels.
See also auditwheel, a tool that package developers use to check and fix Python packages they are making in the binary wheel format. It provides functionality to discover dependencies, check metadata for compliance, and repair the wheel and metadata to properly link and include external shared libraries in a package.
Docs | Issues | PyPI | GitHub
Buildout is a Python-based build system for creating, assembling and deploying applications from multiple parts, some of which may be non-Python-based. It lets you create a buildout configuration and reproduce the same software later.
Docs
conda is the package management tool for Anaconda Python installations. Anaconda Python is a distribution from Anaconda, Inc specifically aimed at the scientific community, and in particular on Windows where the installation of binary extensions is often difficult.
Conda is a completely separate tool from pip, virtualenv and wheel, but provides many of their combined features in terms of package management, virtual environment management and deployment of binary extensions.
Conda does not install packages from PyPI and can install only from the official Anaconda repositories, or anaconda.org (a place for user-contributed conda packages), or a local (e.g. intranet) package server. However, note that pip can be installed into, and work side-by-side with conda for managing distributions from PyPI. Also, conda skeleton is a tool to make Python packages installable by conda by first fetching them from PyPI and modifying their metadata.
devpi features a powerful PyPI-compatible server and PyPI proxy cache with a complementary command line tool to drive packaging, testing and release activities with Python. devpi also provides a browsable and searchable web interface.
Flit provides a simple way to upload pure Python packages and modules to PyPI. It focuses on making the easy things easy for packaging. Flit can generate a configuration file to quickly set up a simple project, build source distributions and wheels, and upload them to PyPI.
Flit uses pyproject.toml
to configure a project. Flit does not rely
on tools such as
setuptools
to build distributions, or
twine
to upload them to PyPI. Flit requires Python
3, but you can use it to distribute modules
for Python 2, so long as they can be
imported on Python 3.
Enscons is a Python packaging tool based on SCons. It builds pip-compatible source distributions and wheels without using distutils or setuptools, including distributions with C extensions. Enscons has a different architecture and philosophy than distutils. Rather than adding build features to a Python packaging system, enscons adds Python packaging to a general purpose build system. Enscons helps you to build sdists that can be automatically built by pip, and wheels that are independent of enscons.
Hashdist is a library for building non-root software distributions. Hashdist is trying to be “the Debian of choice for cases where Debian technology doesn’t work”. The best way for Pythonistas to think about Hashdist may be a more powerful hybrid of virtualenv and buildout. It is aimed at solving the problem of installing scientific software, and making package distribution stateless, cached, and branchable. It is used by some researchers but has been lacking in maintenance since 2016.
GitHub and Docs | PyPI
Hatch is a unified command-line tool meant to conveniently manage dependencies and environment isolation for Python developers. Python package developers use Hatch to configure, version, specify dependencies for, and publish packages to PyPI. Under the hood, it uses twine to upload packages to PyPI, and pip to download and install packages.
GitHub
Multibuild is a set of CI scripts for building and testing Python wheels for Linux, macOS, and (less flexibly) Windows. Also see cibuildwheel.
pex is both a library and tool for
generating .pex
(Python EXecutable) files, standalone Python
environments in the spirit of
virtualenv. .pex
files are just carefully constructed zip
files with a #!/usr/bin/env python
and special __main__.py, and are designed to make deployment of
Python applications as simple as cp.
GitHub and Docs | PyPI
pip-tools is a suite of tools meant for Python system administrators and release managers who particularly want to keep their builds deterministic yet stay up to date with new versions of their dependencies. Users can specify particular release of their dependencies via hash, conveniently make a properly formatted list of requirements from information in other parts of their program, update all dependencies (a feature pip currently does not provide), and create layers of constraints for the program to obey.
piwheels is a website, and software underpinning it, that fetches source code distribution packages from PyPI and compiles them into binary wheels that are optimized for installation onto Raspberry Pi computers. Raspberry Pi OS pre-configures pip to use piwheels.org as an additional index to PyPI.
poetry is a command-line tool to handle
dependency installation and isolation as
well as building and packaging of Python
packages. It uses pyproject.toml
and, instead of depending on the resolver
functionality within
pip, provides its own dependency resolver. It
attempts to speed users’ experience of
installation and dependency resolution by
locally caching metadata about
dependencies.
pypiserver is a minimalist application that serves as a private Python package index within organizations, implementing a simple API and browser interface. You can upload private packages using standard upload tools, and users can download and install them with pip, without publishing them publicly. Organizations who use pypiserver usually download packages both from pypiserver and from PyPI.
Scikit-build is an improved build system generator for CPython C/C++/Fortran/Cython extensions that integrates with setuptools, wheel and pip. It internally uses cmake (available on PyPI) to provide better support for additional compilers, build systems, cross compilation, and locating dependencies and their associated build requirements. To speed up and parallelize the build of large projects, the user can install ninja (also available on PyPI).
shiv is a command line utility for building fully self contained Python zipapps as outlined in PEP 441, but with all their dependencies included. Its primary goal is making distributing Python applications and command line tools fast & easy.
Docs | GitHub | Paper | Slides
A flexible package manager designed to support multiple versions, configurations, platforms, and compilers. Spack is like Homebrew, but packages are written in Python and parameterized to allow easy swapping of compilers, library versions, build options, etc. Arbitrarily many versions of packages can coexist on the same system. Spack was designed for rapidly building high performance scientific applications on clusters and supercomputers.
Spack is not in PyPI (yet), but it requires no installation and can be used immediately after cloning from GitHub.
zest.releaser
is a Python package release tool providing
an abstraction layer on top of
twine. Python developers use zest.releaser
to automate incrementing package version
numbers, updating changelogs, tagging
releases in source control, and uploading
new packages to PyPI.
A package in the Python Standard Library that provides support for bootstrapping pip into an existing Python installation or virtual environment. In most cases, end users won’t use this module, but rather it will be used during the build of the Python distribution.
The original Python packaging system, added to the standard library in Python 2.0.
Due to the challenges of maintaining a packaging system where feature updates are tightly coupled to language runtime updates, direct usage of distutils is now actively discouraged, with setuptools being the preferred replacement. setuptools not only provides features that plain distutils doesn’t offer (such as dependency declarations and entry point declarations), it also provides a consistent build interface and feature set across all supported Python versions.
A package in the Python Standard Library (starting with Python 3.3) for creating Virtual Environments. For more information, see the section on Creating Virtual Environments.